"use strict";
/**
 * Promise
 * @param {*} exextor
 * @value  promise 成功后的值
 * @reason promise失败的原因
 * @status promise的值 初始为pending
 * @resolveCallback promise 成功后执行的回调函数队列
 * @rejectCallback promise 失败后执行的回调函数队列
 *
 * status 仅能从 pending ==> fulfilled or pending ==> rejected
 * promise 的实例拥有then方法
 *
 */
var PENDING = 'pending';
var FULFILLED = 'fulfilled';
var REJECTED = 'rejected';
var MyPromise = /** @class */ (function () {
    function MyPromise(exector) {
        this.status = PENDING;
        this.value = undefined;
        this.reason = undefined;
        this.resolveCallback = [];
        this.rejectCallback = [];
        try {
            exector(this.resolve.bind(this), this.reject.bind(this));
        }
        catch (e) {
            this.reject(e);
        }
    }
    MyPromise.prototype.resolve = function (value) {
        if (this.status === PENDING) {
            this.status = FULFILLED;
            this.value = value;
            this.resolveCallback.forEach(function (cb) {
                cb && cb(value);
            });
        }
    };
    MyPromise.prototype.reject = function (reason) {
        if (this.status === PENDING) {
            this.status = FULFILLED;
            this.reason = reason;
            this.rejectCallback.forEach(function (cb) {
                cb && cb(reason);
            });
        }
    };
    MyPromise.prototype.then = function (onFulfilled, onRejected) {
        var _this = this;
        var fulfillCallback = typeof onFulfilled === 'function' ? onFulfilled : function (value) { return value; };
        var rejectCallback = typeof onRejected === 'function' ? onRejected : function (reason) { throw reason; };
        var promise;
        if (this.status === FULFILLED) {
            return promise = new MyPromise(function (resolve, reject) {
                try {
                    var x = fulfillCallback(_this.value);
                    if (x instanceof MyPromise) {
                        x.then(resolve, reject);
                    }
                    resolve(x);
                }
                catch (e) {
                    reject(e);
                }
            });
        }
        else if (this.status === REJECTED) {
            return promise = new MyPromise(function (resolve, reject) {
                try {
                    var x = rejectCallback(_this.reason);
                    if (x instanceof MyPromise) {
                        x.then(resolve, reject);
                    }
                    reject(x);
                }
                catch (e) {
                    reject(e);
                }
            });
        }
        else {
            return promise = new MyPromise(function (resolve, reject) {
                _this.resolveCallback.push(function (value) {
                    try {
                        var x = fulfillCallback(value);
                        if (x instanceof MyPromise) {
                            x.then(resolve, reject);
                        }
                        resolve(x);
                    }
                    catch (e) {
                        reject(e);
                    }
                });
                _this.rejectCallback.push(function (reason) {
                    try {
                        var x = rejectCallback(reason);
                        if (x instanceof MyPromise) {
                            x.then(resolve, reject);
                        }
                        reject(x);
                    }
                    catch (e) {
                        reject(e);
                    }
                });
            });
        }
    };
    MyPromise.prototype.catch = function (onRejected) {
        this.then(null, onRejected);
    };
    return MyPromise;
}());
console.log(1);
var p1 = new Promise(function (resolve, reject) {
    setTimeout(function () {
        reject(1);
    }, 1000);
});
var p2 = new Promise(function (resolve, reject) {
    console.log(2);
    setTimeout(function () {
        resolve(p1);
    });
}).then(function (res) {
    console.log(res);
});
console.log(p2);
